package producer;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioChannelOption;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.channel.unix.PreferredDirectByteBufAllocator;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.DefaultThreadFactory;
import producer.handler.RpcHandler;

/**
 * @ClassName AppServer
 * @Description
 * @Author Jingxiao.Ye
 * @Date 2022/1/2 下午11:39
 * @Version V1.0
 * @Since JDK 11
 */
public class AppServer {

    public static void main(String[] args) {
        String port = System.getProperty("producer.port", "8081");
        init(Integer.parseInt(port));
    }

    public static void init(int port){
        EventLoopGroup boss = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors()*2,new DefaultThreadFactory("boss"));
        EventLoopGroup work = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors()*2,new DefaultThreadFactory("work"));
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap().group(boss,work)
                    .option(NioChannelOption.SO_BACKLOG,1024*1024)
                    .childOption(NioChannelOption.SO_REUSEADDR,true)
                    .childOption(NioChannelOption.SO_KEEPALIVE,false)
                    .childOption(NioChannelOption.SO_SNDBUF,1024*256)
                    .childOption(NioChannelOption.SO_RCVBUF,1024*256)
                    .option(NioChannelOption.ALLOCATOR, new PreferredDirectByteBufAllocator())
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<NioSocketChannel>() {
                        protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                            ChannelPipeline p = nioSocketChannel.pipeline();
                            p.addLast(new HttpServerCodec());
                            p.addLast(new HttpObjectAggregator(1024*128));
                            p.addLast(new RpcHandler());
                        }
                    });
            serverBootstrap.bind(port).sync().channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            boss.shutdownGracefully();
            work.shutdownGracefully();
        }
    }
}
